package com.mengfou.mytvapp;

import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.webkit.ValueCallback;
import android.webkit.WebChromeClient;
import android.webkit.WebResourceError;
import android.webkit.WebResourceRequest;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import androidx.fragment.app.FragmentActivity;
import com.mengfou.mytvapp.util.MyThreadTool;
import com.mengfou.mytvapp.util.PageElementObserver;
import com.mengfou.mytvapp.util.UserKeyEventHelper;
import java.util.HashSet;
import java.util.Set;

/**
 * https://blog.csdn.net/devilnov/article/details/117323956
 */
public class MainActivity extends FragmentActivity implements PageElementObserver{
    private String TAG = MainActivity.class.getName();
    private WebView webView;
    private TextView pageload_info;
    private TextView bottom_info_text;
    private LinearLayout text_info;
    private LinearLayout bottom_info;
    private int currentShowIndex = 13; // 1~17
    private final Set<Integer> invalidShowIndexs = new HashSet<>();
    private boolean currentPageLoadFlag = false;
    private MyThreadTool myThreadTool;
    private UserKeyEventHelper userKeyEventHelper;
    private boolean pageHasFinished;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        webView = findViewById(R.id.load_page);
        pageload_info = findViewById(R.id.pageload_info);
        text_info = findViewById(R.id.text_info);
        bottom_info = findViewById(R.id.bottom_info);
        bottom_info_text = findViewById(R.id.bottom_info_text);
        myThreadTool = new MyThreadTool();
        userKeyEventHelper = new UserKeyEventHelper(3);
        invalidShowIndexs.add(3);
        invalidShowIndexs.add(14);

        initWebView();

        loadPage();
    }

    @SuppressLint("SetJavaScriptEnabled")
    private void initWebView() {
        webView.setWebViewClient(new WebViewClient(){
            @Override
            public void onPageFinished(WebView view, String url) {
                super.onPageFinished(view, url);
                currentPageLoadFlag = true;
                doExecuteJavaScript(new ElementExecuteListener() {
                    @Override
                    public void onFinish() {
                        setWebViewVisibility(true);
                    }
                });
                Toast.makeText(MainActivity.this, "CCTV"+ currentShowIndex +"频道", Toast.LENGTH_SHORT).show();
                checkPageFullScreenElement();
            }

            @Override
            public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
                super.onReceivedError(view, request, error);
                onPageLoaderError();
            }

            @Override
            public void onPageStarted(WebView view, String url, Bitmap favicon) {
                super.onPageStarted(view, url, favicon);
                setWebViewVisibility(false);
            }

            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                view.loadUrl(url);
                return true;
            }

            @Override
            public void onLoadResource(WebView view, String url) {
                super.onLoadResource(view, url);
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        if(!pageHasFinished) {
                            if(bottom_info.getVisibility() == View.INVISIBLE) {
                                bottom_info.setVisibility(View.VISIBLE);
                            }
                            if(bottom_info_text.getVisibility() == View.INVISIBLE) {
                                bottom_info_text.setVisibility(View.VISIBLE);
                            }
                            bottom_info_text.setText(url);
                        }
                    }
                });
            }
        });

        webView.setWebChromeClient(new WebChromeClient(){
            @Override
            public void onProgressChanged(WebView view, int newProgress) {
                super.onProgressChanged(view, newProgress);
                runOnUiThread(new Runnable() {
                    @SuppressLint("SetTextI18n")
                    @Override
                    public void run() {
                        pageload_info.setText("加载中... "+newProgress+"%");
                    }
                });
            }
        });


        WebSettings settings = webView.getSettings();
        settings.setJavaScriptEnabled(true);
        settings.setJavaScriptCanOpenWindowsAutomatically(true);
        settings.setRenderPriority(WebSettings.RenderPriority.HIGH);
        settings.setLoadsImagesAutomatically(true);
        settings.setLoadWithOverviewMode(true);
        settings.setUseWideViewPort(true);
        settings.setAllowFileAccess(true);
        settings.setAllowContentAccess(true);
        settings.setBlockNetworkImage(false);
    }

    private void checkPageFullScreenElement() {
        webView.evaluateJavascript( "function test() {" +
                "return document.getElementById('"+"player_pagefullscreen_no_player"+"');" +
                "}" +
                "test();", new ValueCallback<String>() {
            @Override
            public void onReceiveValue(String value) {
                hasFullScreenBtnObserver(value != null);
            }
        });
    }

    private void loadPage() {
       runOnUiThread(new Runnable(){
            @Override
            public void run() {
                webView.loadUrl("https://tv.cctv.com/live/cctv"+currentShowIndex+"/m/");
                currentPageLoadFlag = false;

                myThreadTool.execute(new Runnable() {
                    @Override
                    public void run() {
                        onPageLoaderError();
                    }
                }, 10000);
            }
        });
    }

    private void onPageLoaderError() {
        if(!currentPageLoadFlag) {
            invalidShowIndexs.add(currentShowIndex);
            nextPage(userKeyEventHelper.getLastDownOrUpKeyEvent());
        }
    }

    private void doExecuteJavaScript(ElementExecuteListener listener) {
        doStartOrStopPlay();
        doFullScreen(listener);
    }

    private void doStartOrStopPlay() {
        webView.loadUrl("javascript:(function() { " +
                "var videos = document.getElementsByTagName('video');" +
                " for(var i=0;i<videos.length;i++){videos[i].play();}})()");
    }

    private void doFullScreen(ElementExecuteListener listener) {
        webView.evaluateJavascript("javascript:(function() {" +
                "var img = document.getElementById('"+"player_pagefullscreen_no_player"+"');" +
                "var event = new MouseEvent('click', {" +
                "    bubbles: true, " +
                "    cancelable: true, " +
                "});" +
                "img.dispatchEvent(event);})()", new ValueCallback<String>() {
            @Override
            public void onReceiveValue(String value) {
                if(listener != null) {
                    listener.onFinish();
                }
            }
        });
    }

    @Override
    public void hasFullScreenBtnObserver(boolean exist) {
        onPageLoaderError();
    }


    interface ElementExecuteListener {
        void onFinish();
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            if (event.getRepeatCount() == 0) {
                dialog("确认退出？");
                return false;
            }
        }
        return super.onKeyDown(keyCode, event);
    }

    @SuppressLint("RestrictedApi")
    @Override
    public boolean dispatchKeyEvent(KeyEvent event) {
        switch(event.getKeyCode()) {
            case KeyEvent.KEYCODE_DPAD_UP:
                if(currentPageLoadFlag) {
                    nextPage(UserKeyEvent.UP);
                }
                userKeyEventHelper.addKeyEvent(UserKeyEvent.UP);
                break;
            case KeyEvent.KEYCODE_DPAD_DOWN:
                if(currentPageLoadFlag) {
                    nextPage(UserKeyEvent.DOWN);
                }
                userKeyEventHelper.addKeyEvent(UserKeyEvent.DOWN);
                break;
        }
        return super.dispatchKeyEvent(event);
    }

    private void nextPage(UserKeyEvent forward) {
        if(forward == UserKeyEvent.UP) {
            currentShowIndex = (currentShowIndex + 1) % 17;
        } else if(forward == UserKeyEvent.DOWN) {
            currentShowIndex = (currentShowIndex - 1) % 17;
        } else {
            return;
        }
        if(invalidShowIndexs.contains(currentShowIndex)) {
            nextPage(forward);
        }
        loadPage();
    }

    private void dialog(String message) {
        AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
        builder.setMessage(message);
        builder.setPositiveButton("确认", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
                webView.pauseTimers();
                webView = null;
                MainActivity.this.finish();
            }
        });
        builder.create().show();
    }

    private void setWebViewVisibility(boolean visibility) {
        webView.setVisibility(visibility ? View.VISIBLE : View.GONE);
        text_info.setVisibility(!visibility ? View.VISIBLE : View.GONE);
        pageHasFinished = visibility;
        if(pageHasFinished) {
            bottom_info_text.setVisibility(View.INVISIBLE);
            bottom_info.setVisibility(View.INVISIBLE);
        }
    }
}